package org.dreamwork.cai.io.netty;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import org.dreamwork.cai.io.AbstractServiceProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class NettyServiceProvider extends AbstractServiceProvider {
    private final Logger logger = LoggerFactory.getLogger (NettyServiceProvider.class);

    private final EventLoopGroup group = new NioEventLoopGroup ();

    @Override
    public void bind (int port) {
        ServerBootstrap server = new ServerBootstrap ();
        server.group (group);
        server.option (ChannelOption.SO_REUSEADDR, true);
        server.localAddress (port);
        server.channel (NioServerSocketChannel.class);
        server.childHandler (new ChannelInitializer<NioSocketChannel> () {
            @Override
            protected void initChannel (NioSocketChannel ch) throws Exception {
                ch.pipeline ()
                        .addLast (new Codec.Encoder ())
                        .addLast (new Codec.Decoder ())
                        .addLast (new ServiceProviderAdapter (resolver));
            }
        });

        Channel channel = server.bind ().syncUninterruptibly ().channel ();
        logger.info ("netty service provider listen on {}", channel.localAddress ());
    }

    @Override
    public void unbind () {
        group.shutdownGracefully ();
    }
}
